home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / osrc.arc / TCPIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-06  |  22.6 KB  |  853 lines

  1. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  2.  * the TCP specification.
  3.  */
  4.  
  5. #include "global.h"
  6. #include "timer.h"
  7. #include "mbuf.h"
  8. #include "netuser.h"
  9. #include "internet.h"
  10. #include "tcp.h"
  11. #include "icmp.h"
  12. #include "iface.h"
  13. #include "ip.h"
  14.  
  15. void reset(),send_syn();
  16. static void update(),proc_syn(),add_reseq(),get_reseq();
  17. static int trim();
  18.  
  19. struct tcp_stat Tcp_stat;
  20.  
  21. /* This function is called from IP with the IP header in machine byte order,
  22.  * along with a mbuf chain pointing to the TCP header.
  23.  */
  24. void
  25. tcp_input(bp,protocol,source,dest,tos,length,rxbroadcast)
  26. struct mbuf *bp;    /* Data field, if any */
  27. char protocol;        /* Should always be TCP_PTCL */
  28. int32 source;        /* Remote IP address */
  29. int32 dest;        /* Our IP address */
  30. char tos;        /* Type of Service */
  31. int16 length;        /* Length of data field */
  32. int rxbroadcast;    /* Incoming broadcast - discard if true */
  33. {
  34.     register struct tcb *tcb;    /* TCP Protocol control block */
  35.     struct tcp seg;            /* Local copy of segment header */
  36.     struct connection conn;        /* Local copy of addresses */
  37.     struct pseudo_header ph;    /* Pseudo-header for checksumming */
  38.     int hdrlen;            /* Length of TCP header */
  39.  
  40.     if(bp == NULLBUF)
  41.         return;
  42.  
  43.     if(rxbroadcast){
  44.         /* Any TCP packet arriving as a broadcast is
  45.          * to be completely IGNORED!!
  46.          */
  47.         Tcp_stat.bdcsts++;
  48.         free_p(bp);
  49.         return;
  50.     }
  51.     ph.source = source;
  52.     ph.dest = dest;
  53.     ph.protocol = protocol;
  54.     ph.length = length;
  55.     if(cksum(&ph,bp,length) != 0){
  56.         /* Checksum failed, ignore segment completely */
  57.         Tcp_stat.checksum++;
  58.         free_p(bp);
  59.         return;
  60.     }
  61.     /* Form local copy of TCP header in host byte order */
  62.     if((hdrlen = ntohtcp(&seg,&bp)) < 0){
  63.         /* TCP header is too small */
  64.         Tcp_stat.runt++;
  65.         free_p(bp);
  66.         return;
  67.     }
  68.     length -= hdrlen;
  69.  
  70.     /* Fill in connection structure and find TCB */
  71.     conn.local.address = dest;
  72.     conn.local.port = seg.dest;
  73.     conn.remote.address = source;
  74.     conn.remote.port = seg.source;
  75.     
  76.     if((tcb = lookup_tcb(&conn)) == NULLTCB){
  77.         struct tcb *ntcb;
  78.  
  79.         /* Check that this segment carries a SYN, and that
  80.          * there's a LISTEN on this socket with
  81.          * unspecified source address and port
  82.          */
  83.         conn.remote.address = 0;
  84.         conn.remote.port = 0;
  85.         if(!seg.flags.syn || (tcb = lookup_tcb(&conn)) == NULLTCB){
  86.             /* No unspecified LISTEN either, so reject */
  87.             free_p(bp);
  88.             reset(source,dest,tos,length,&seg);
  89.             return;
  90.         }
  91.         /* We've found an server listen socket, so clone the TCB */
  92.         if(tcb->flags.clone){
  93.             if((ntcb = (struct tcb *)malloc(sizeof (struct tcb))) == NULLTCB){
  94.                 free_p(bp);
  95.                 /* This may fail, but we should at least try */
  96.                 reset(source,dest,tos,length,&seg);
  97.                 return;
  98.             }
  99.             ASSIGN(*ntcb,*tcb);
  100.             tcb = ntcb;
  101.             tcb->timer.arg = (char *)tcb;
  102.         } else
  103.             unlink_tcb(tcb);    /* It'll be put back on later */
  104.  
  105.         /* Stuff the foreign socket into the TCB */
  106.         tcb->conn.remote.address = source;
  107.         tcb->conn.remote.port = seg.source;
  108.  
  109.         /* NOW put on right hash chain */
  110.         link_tcb(tcb);
  111.     }
  112.     /* Do unsynchronized-state processing (p. 65-68) */
  113.     switch(tcb->state){
  114.     case CLOSED:
  115.         free_p(bp);
  116.         reset(source,dest,tos,length,&seg);
  117.         return;
  118.     case LISTEN:
  119.         if(seg.flags.rst){
  120.             free_p(bp);
  121.             return;
  122.         }
  123.         if(seg.flags.ack){
  124.             free_p(bp);
  125.             reset(source,dest,tos,length,&seg);
  126.             return;
  127.         }
  128.         if(seg.flags.syn){
  129.             /* (Security check is bypassed) */
  130.             /* page 66 */
  131.             Tcp_stat.conin++;
  132.             proc_syn(tcb,tos,&seg);
  133.             send_syn(tcb);
  134.             setstate(tcb,SYN_RECEIVED);        
  135.             if(length != 0 || seg.flags.fin) {
  136.                 /* Continue processing if there's more */
  137.                 break;
  138.             }
  139.             tcp_output(tcb);
  140.         }
  141.         free_p(bp);    /* Unlikely to get here directly */
  142.         return;
  143.     case SYN_SENT:
  144.         if(seg.flags.ack){
  145.             if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt)){
  146.                 free_p(bp);
  147.                 reset(source,dest,tos,length,&seg);
  148.                 return;
  149.             }
  150.         }
  151.         if(seg.flags.rst){    /* p 67 */
  152.             if(seg.flags.ack){
  153.                 /* The ack must be acceptable since we just checked it.
  154.                  * This is how the remote side refuses connect requests.
  155.                  */
  156.                 close_self(tcb,RESET);
  157.             }
  158.             free_p(bp);
  159.             return;
  160.         }
  161.         /* (Security check skipped here) */
  162.         /* Check incoming precedence; it must match if there's an ACK */
  163.         if(seg.flags.ack && PREC(tos) != PREC(tcb->tos)){
  164.             free_p(bp);
  165.             reset(source,dest,tos,length,&seg);
  166.             return;
  167.         }
  168.         if(seg.flags.syn){
  169.             proc_syn(tcb,tos,&seg);
  170.             if(seg.flags.ack){
  171.                 /* Our SYN has been acked, otherwise the ACK
  172.                  * wouldn't have been valid.
  173.                  */
  174.                 update(tcb,&seg);
  175.                 setstate(tcb,ESTABLISHED);
  176.             } else {
  177.                 setstate(tcb,SYN_RECEIVED);
  178.             }
  179.             if(length != 0 || seg.flags.fin) {
  180.                 break;        /* Continue processing if there's more */
  181.             }
  182.             tcp_output(tcb);
  183.         } else {
  184.             free_p(bp);    /* Ignore if neither SYN or RST is set */
  185.         }
  186.         return;
  187.     }
  188.     /* We reach this point directly in any synchronized state. Note that
  189.      * if we fell through from LISTEN or SYN_SENT processing because of a
  190.      * data-bearing SYN, window trimming and sequence testing "cannot fail".
  191.      */
  192.  
  193.     /* Trim segment to fit receive window. */
  194.     if(trim(tcb,&seg,&bp,&length) == -1){
  195.         /* Segment is unacceptable */
  196.         if(!seg.flags.rst){    /* NEVER answer RSTs */
  197.             /* In SYN_RECEIVED state, answer a retransmitted SYN 
  198.              * with a retransmitted SYN/ACK.
  199.              */
  200.             if(tcb->state == SYN_RECEIVED)
  201.                 tcb->snd.ptr = tcb->snd.una;
  202.             tcb->flags.force = 1;
  203.             tcp_output(tcb);
  204.         }
  205.         return;
  206.     }
  207.     /* If segment isn't the next one expected, and there's data
  208.      * or flags associated with it, put it on the resequencing
  209.      * queue, ACK it and return.
  210.      *
  211.      * Processing the ACK in an out-of-sequence segment without
  212.      * flags or data should be safe, however.
  213.      */
  214.     if(seg.seq != tcb->rcv.nxt
  215.      && (length != 0 || seg.flags.syn || seg.flags.fin)){
  216.         add_reseq(tcb,tos,&seg,bp,length);
  217.         tcb->flags.force = 1;
  218.         tcp_output(tcb);
  219.         return;
  220.     }
  221.     /* This loop first processes the current segment, and then
  222.      * repeats if it can process the resequencing queue.
  223.      */
  224.     for(;;){
  225.         /* We reach this point with an acceptable segment; all data and flags
  226.          * are in the window, and the starting sequence number equals rcv.nxt
  227.          * (p. 70)
  228.          */    
  229.         if(seg.flags.rst){
  230.             if(tcb->state == SYN_RECEIVED
  231.              && !tcb->flags.clone && !tcb->flags.active){
  232.                 /* Go back to listen state only if this was
  233.                  * not a cloned or active server TCB
  234.                  */
  235.                 setstate(tcb,LISTEN);
  236.             } else {
  237.                 close_self(tcb,RESET);
  238.             }
  239.             free_p(bp);
  240.             return;
  241.         }
  242.         /* (Security check skipped here) p. 71 */
  243.         /* Check for precedence mismatch or erroneous extra SYN */
  244.         if(PREC(tos) != PREC(tcb->tos) || seg.flags.syn){
  245.             free_p(bp);
  246.             reset(source,dest,tos,length,&seg);
  247.             return;
  248.         }
  249.         /* Check ack field p. 72 */
  250.         if(!seg.flags.ack){
  251.             free_p(bp);    /* All segments after synchronization must have ACK */
  252.             return;
  253.         }
  254.         /* Process ACK */
  255.         switch(tcb->state){
  256.         case SYN_RECEIVED:
  257.             if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  258.                 update(tcb,&seg);
  259.                 setstate(tcb,ESTABLISHED);
  260.             } else {
  261.                 free_p(bp);
  262.                 reset(source,dest,tos,length,&seg);
  263.                 return;
  264.             }
  265.             break;
  266.         case ESTABLISHED:
  267.         case CLOSE_WAIT:
  268.             update(tcb,&seg);
  269.             break;
  270.         case FINWAIT1:    /* p. 73 */
  271.             update(tcb,&seg);
  272.             if(tcb->sndcnt == 0){
  273.                 /* Our FIN is acknowledged */
  274.                 setstate(tcb,FINWAIT2);
  275.             }
  276.             break;
  277.         case FINWAIT2:
  278.             update(tcb,&seg);
  279.             break;
  280.         case CLOSING:
  281.             update(tcb,&seg);
  282.             if(tcb->sndcnt == 0){
  283.                 /* Our FIN is acknowledged */
  284.                 setstate(tcb,TIME_WAIT);
  285.                 tcb->timer.start = MSL2 * (1000 / MSPTICK);
  286.                 start_timer(&tcb->timer);
  287.             }
  288.             break;
  289.         case LAST_ACK:
  290.             update(tcb,&seg);
  291.             if(tcb->sndcnt == 0){
  292.                 /* Our FIN is acknowledged, close connection */
  293.                 close_self(tcb,NORMAL);
  294.                 return;
  295.             }            
  296.             break;
  297.         case TIME_WAIT:
  298.             start_timer(&tcb->timer);
  299.             break;
  300.         }
  301.  
  302.         /* (URGent bit processing skipped here) */
  303.  
  304.         /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  305.         if(length != 0){
  306.             switch(tcb->state){
  307.             case SYN_RECEIVED:
  308.             case ESTABLISHED:
  309.             case FINWAIT1:
  310.             case FINWAIT2:
  311.                 /* Place on receive queue */
  312.                 append(&tcb->rcvq,bp);
  313.                 tcb->rcvcnt += length;
  314.                 tcb->rcv.nxt += length;
  315.                 tcb->rcv.wnd -= length;
  316.                 tcb->flags.force = 1;
  317.                 /* Notify user */
  318.                 if(tcb->r_upcall)
  319.                     (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  320.                 break;
  321.             default:
  322.                 /* Ignore segment text */
  323.                 free_p(bp);
  324.                 break;
  325.             }
  326.         }
  327.         /* process FIN bit (p 75) */
  328.         if(seg.flags.fin){
  329.             tcb->flags.force = 1;    /* Always respond with an ACK */
  330.  
  331.             switch(tcb->state){
  332.             case SYN_RECEIVED:
  333.             case ESTABLISHED:
  334.                 tcb->rcv.nxt++;
  335.                 setstate(tcb,CLOSE_WAIT);
  336.                 break;
  337.             case FINWAIT1:
  338.                 tcb->rcv.nxt++;
  339.                 if(tcb->sndcnt == 0){
  340.                     /* Our FIN has been acked; bypass CLOSING state */
  341.                     setstate(tcb,TIME_WAIT);
  342.                     tcb->timer.start = MSL2 * (1000/MSPTICK);
  343.                     start_timer(&tcb->timer);
  344.                 } else {
  345.                     setstate(tcb,CLOSING);
  346.                 }
  347.                 break;
  348.             case FINWAIT2:
  349.                 tcb->rcv.nxt++;
  350.                 setstate(tcb,TIME_WAIT);
  351.                 tcb->timer.start = MSL2 * (1000/MSPTICK);
  352.                 start_timer(&tcb->timer);
  353.                 break;
  354.             case CLOSE_WAIT:
  355.             case CLOSING:
  356.             case LAST_ACK:
  357.                 break;        /* Ignore */
  358.             case TIME_WAIT:    /* p 76 */
  359.                 start_timer(&tcb->timer);
  360.                 break;
  361.             }
  362.             /* Call the client again so he can see EOF */
  363.             if(tcb->r_upcall)
  364.                 (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  365.         }
  366.         /* Scan the resequencing queue, looking for a segment we can handle,
  367.          * and freeing all those that are now obsolete.
  368.          */
  369.         while(tcb->reseq != NULLRESEQ && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  370.             get_reseq(tcb,&tos,&seg,&bp,&length);
  371.             if(trim(tcb,&seg,&bp,&length) == 0)
  372.                 goto gotone;
  373.             /* Segment is an old one; trim has freed it */
  374.         }
  375.         break;
  376. gotone:    ;
  377.     }
  378.     tcp_output(tcb);    /* Send any necessary ack */
  379. }
  380.  
  381. /* Process an incoming ICMP response */
  382. void
  383. tcp_icmp(source,dest,type,code,bpp)
  384. int32 source;            /* Original IP datagram source (i.e. us) */
  385. int32 dest;            /* Original IP datagram dest (i.e., them) */
  386. char type,code;            /* ICMP error codes */
  387. struct mbuf **bpp;        /* First 8 bytes of TCP header */
  388. {
  389.     struct tcp seg;
  390.     struct connection conn;
  391.     register struct tcb *tcb;
  392.  
  393.     /* Extract the socket info from the returned TCP header fragment
  394.      * Note that since this is a datagram we sent, the source fields
  395.      * refer to the local side.
  396.      */
  397.     ntohtcp(&seg,bpp);
  398.     conn.local.port = seg.source;
  399.     conn.remote.port = seg.dest;
  400.     conn.local.address = source;
  401.     conn.remote.address = dest;
  402.     if((tcb = lookup_tcb(&conn)) == NULLTCB)
  403.         return;    /* Unknown connection, ignore */
  404.  
  405.     /* Verify that the sequence number in the returned segment corresponds
  406.      * to something currently unacknowledged. If not, it can safely
  407.      * be ignored.
  408.      */
  409.     if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  410.         return;
  411.  
  412.     /* The strategy here is that Destination Unreachable and Time Exceeded
  413.      * messages that occur after a connection has been established are likely
  414.      * to be transient events, and shouldn't kill our connection (at least
  415.      * until after we've tried a few more times). On the other hand, if
  416.      * they occur on our very first attempt to send a datagram on a new
  417.      * connection, they're probably "for real". In any event, the info
  418.      * is saved.
  419.      */
  420.     switch(uchar(type)){
  421.     case DEST_UNREACH:
  422.     case TIME_EXCEED:
  423.         tcb->type = type;
  424.         tcb->code = code;
  425.         if(tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED){
  426.             close_self(tcb,NETWORK);
  427.         }
  428.         break;
  429.     case QUENCH:
  430.         /* Source quench; cut the congestion window in half,
  431.          * but don't let it go below one packet
  432.          */
  433.         tcb->cwind /= 2;
  434.         tcb->cwind = max(tcb->mss,tcb->cwind);
  435.         break;
  436.     }
  437. }
  438. /* Send an acceptable reset (RST) response for this segment
  439.  * The RST reply is composed in place on the input segment
  440.  */
  441. void
  442. reset(source,dest,tos,length,seg)
  443. int32 source;            /* Remote IP address */
  444. int32 dest;            /* Our IP address */
  445. char tos;            /* Type of Service */
  446. int16 length;            /* Length of data portion */
  447. register struct tcp *seg;    /* Offending TCP header */
  448. {
  449.     struct mbuf *hbp;
  450.     struct pseudo_header ph;
  451.     int16 tmp;
  452.  
  453.     if(seg->flags.rst)
  454.         return;    /* Never send an RST in response to an RST */
  455.  
  456.     Tcp_stat.resets++;
  457.  
  458.     /* Compose the RST IP pseudo-header, swapping addresses */
  459.     ph.source = dest;
  460.     ph.dest = source;
  461.     ph.protocol = TCP_PTCL;
  462.     ph.length = TCPLEN;
  463.  
  464.     /* Swap port numbers */
  465.     tmp = seg->dest;
  466.     seg->dest = seg->source;
  467.     seg->source = tmp;
  468.  
  469.     if(seg->flags.ack){
  470.         /* This reset is being sent to clear a half-open connection.
  471.          * Set the sequence number of the RST to the incoming ACK
  472.          * so it will be acceptable.
  473.          */
  474.         seg->flags.ack = 0;
  475.         seg->seq = seg->ack;
  476.         seg->ack = 0;
  477.     } else {
  478.         /* We're rejecting a connect request (SYN) from LISTEN state
  479.          * so we have to "acknowledge" their SYN.
  480.          */
  481.         seg->flags.ack = 1;
  482.         seg->ack = seg->seq;
  483.         seg->seq = 0;
  484.         if(seg->flags.syn)
  485.             seg->ack++;
  486.         seg->ack += length;
  487.         if(seg->flags.fin)
  488.             seg->ack++;
  489.     }
  490.     /* Set remaining parts of packet */
  491.     seg->flags.urg = 0;
  492.     seg->flags.psh = 0;
  493.     seg->flags.rst = 1;
  494.     seg->flags.syn = 0;
  495.     seg->flags.fin = 0;
  496.     seg->wnd = 0;
  497.     seg->up = 0;
  498.     seg->mss = 0;
  499.     if((hbp = htontcp(seg,NULLBUF,&ph)) == NULLBUF)
  500.         return;
  501.     /* Ship it out (note swap of addresses) */
  502.     ip_send(dest,source,TCP_PTCL,tos,0,hbp,ph.length,0,0);
  503. }
  504.  
  505. /* Process an incoming acknowledgement and window indication.
  506.  * From page 72.
  507.  */
  508. static void
  509. update(tcb,seg)
  510. register struct tcb *tcb;
  511. register struct tcp *seg;
  512. {
  513.     int16 acked;
  514.     int16 expand;
  515.  
  516.     acked = 0;
  517.     if(seq_gt(seg->ack,tcb->snd.nxt)){
  518.         tcb->flags.force = 1;    /* Acks something not yet sent */
  519.         return;
  520.     }
  521.     /* Decide if we need to do a window update.
  522.      * This is always checked whenever a legal ACK is received,
  523.      * even if it doesn't actually acknowledge anything,
  524.      * because it might be a spontaneous window reopening.
  525.      */
  526.     if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1) 
  527.      && seq_ge(seg->ack,tcb->snd.wl2))){
  528.         /* If the window had been closed, crank back the
  529.          * send pointer so we'll immediately resume transmission.
  530.          * Otherwise we'd have to wait until the next probe.
  531.          */
  532.         if(tcb->snd.wnd == 0 && seg->wnd != 0)
  533.             tcb->snd.ptr = tcb->snd.una;
  534.         tcb->snd.wnd = seg->wnd;
  535.         tcb->snd.wl1 = seg->seq;
  536.         tcb->snd.wl2 = seg->ack;
  537.     }
  538.     /* See if anything new is being acknowledged */
  539.     if(!seq_gt(seg->ack,tcb->snd.una))
  540.         return;    /* Nothing more to do */
  541.  
  542.     /* We're here, so the ACK must have actually acked something */
  543.     acked = seg->ack - tcb->snd.una;
  544.  
  545.     /* Expand congestion window if not already at limit */
  546.     if(tcb->cwind < tcb->snd.wnd){
  547.         if(tcb->cwind < tcb->ssthresh){
  548.             /* Still doing slow start/CUTE, expand by amount acked */
  549.             expand = min(acked,tcb->mss);
  550.         } else {
  551.             /* Steady-state test of extra path capacity */
  552.             expand = ((long)tcb->mss * tcb->mss) / tcb->cwind;
  553.         }
  554.         /* Guard against arithmetic overflow */
  555.         if(tcb->cwind + expand < tcb->cwind)
  556.             expand = MAXINT16 - tcb->cwind;
  557.  
  558.         /* Don't expand beyond the offered window */
  559.         if(tcb->cwind + expand > tcb->snd.wnd)
  560.             expand = tcb->snd.wnd - tcb->cwind;
  561.  
  562.         if(expand != 0){
  563. #ifdef    notdef
  564.             /* Kick up the mean deviation estimate to prevent
  565.              * unnecessary retransmission should we already be
  566.              * bandwidth limited
  567.              */
  568.             tcb->mdev += ((long)tcb->srtt * expand) / tcb->cwind;
  569. #endif
  570.             tcb->cwind += expand;
  571.         }
  572.     }
  573.     /* Round trip time estimation */
  574.     if(tcb->flags.rtt_run && seq_ge(seg->ack,tcb->rttseq)){
  575.         /* A timed sequence number has been acked */
  576.         tcb->flags.rtt_run = 0;
  577.         if(!(tcb->flags.retran)){
  578.             int32 rtt;    /* measured round trip time */
  579.             int32 abserr;    /* abs(rtt - srtt) */
  580.  
  581.             /* This packet was sent only once and now
  582.              * it's been acked, so process the round trip time
  583.              */
  584.             rtt = (Clock - tcb->rtt_time) * MSPTICK;
  585.  
  586.             /* If this ACKs our SYN, this is the first ACK
  587.              * we've received; base our entire SRTT estimate
  588.              * on it. Otherwise average it in with the prior
  589.              * history, also computing mean deviation.
  590.              */
  591.             if(rtt > tcb->srtt &&
  592.              (tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED)){
  593.                 tcb->srtt = rtt;
  594.             } else {
  595.                 abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  596.                 /* Run SRTT and MDEV integrators, with rounding */
  597.                 tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt + (AGAIN/2)) >> LAGAIN;
  598.                 tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr + (DGAIN/2)) >> LDGAIN;
  599.             }
  600.             rtt_add(tcb->conn.remote.address,rtt);
  601.             /* Reset the backoff level */
  602.             tcb->backoff = 0;
  603.         }
  604.     }
  605.     /* If we're waiting for an ack of our SYN, note it and adjust count */
  606.     if(!(tcb->flags.synack)){
  607.         tcb->flags.synack = 1;
  608.         acked--;
  609.         tcb->sndcnt--;
  610.     }
  611.     /* Remove acknowledged bytes from the send queue and update the
  612.      * unacknowledged pointer. If a FIN is being acked,
  613.      * pullup won't be able to remove it from the queue.
  614.      */
  615.     pullup(&tcb->sndq,NULLCHAR,acked);
  616.  
  617.     /* This will include the FIN if there is one */
  618.     tcb->sndcnt -= acked;
  619.     tcb->snd.una = seg->ack;
  620.  
  621.     /* Stop retransmission timer, but restart it if there is still
  622.      * unacknowledged data.
  623.      */    
  624.     stop_timer(&tcb->timer);
  625.     if(tcb->snd.una != tcb->snd.nxt)
  626.         start_timer(&tcb->timer);
  627.  
  628.     /* If retransmissions have been occurring, make sure the
  629.      * send pointer doesn't repeat ancient history
  630.      */
  631.     if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  632.         tcb->snd.ptr = tcb->snd.una;
  633.  
  634.     /* Clear the retransmission flag since the oldest
  635.      * unacknowledged segment (the only one that is ever retransmitted)
  636.      * has now been acked.
  637.      */
  638.     tcb->flags.retran = 0;
  639.  
  640.     /* If outgoing data was acked, notify the user so he can send more
  641.      * unless we've already sent a FIN.
  642.      */
  643.     if(acked != 0){
  644.         switch(tcb->state){
  645.          case ESTABLISHED:
  646.         case CLOSE_WAIT:
  647.             if(tcb->t_upcall){
  648.                 (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  649.             }
  650.         }
  651.     }
  652. }
  653.  
  654. /* Determine if the given sequence number is in our receiver window.
  655.  * NB: must not be used when window is closed!
  656.  */
  657. static
  658. int
  659. in_window(tcb,seq)
  660. struct tcb *tcb;
  661. int32 seq;
  662. {
  663.     return seq_within(seq,tcb->rcv.nxt,(int32)(tcb->rcv.nxt+tcb->rcv.wnd-1));
  664. }
  665.  
  666. /* Process an incoming SYN */
  667. static void
  668. proc_syn(tcb,tos,seg)
  669. register struct tcb *tcb;
  670. char tos;
  671. struct tcp *seg;
  672. {
  673.     int16 mtu;
  674.     struct tcp_rtt *tp;
  675.  
  676.     tcb->flags.force = 1;    /* Always send a response */
  677.  
  678.     /* Note: It's not specified in RFC 793, but SND.WL1 and
  679.      * SND.WND are initialized here since it's possible for the
  680.      * window update routine in update() to fail depending on the
  681.      * IRS if they are left unitialized.
  682.      */
  683.     /* Check incoming precedence and increase if higher */
  684.     if(PREC(tos) > PREC(tcb->tos))
  685.         tcb->tos = tos;
  686.     tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  687.     tcb->snd.wl1 = tcb->irs = seg->seq;
  688.     tcb->snd.wnd = seg->wnd;
  689.     if(seg->mss != 0)
  690.         tcb->mss = seg->mss;
  691.     /* Check the MTU of the interface we'll use to reach this guy
  692.      * and lower the MSS so that unnecessary fragmentation won't occur
  693.      */
  694.     if((mtu = ip_mtu(tcb->conn.remote.address)) != 0){
  695.         /* Allow space for the TCP and IP headers */
  696.         mtu -= TCPLEN + IPLEN;
  697.         tcb->cwind = tcb->mss = min(mtu,tcb->mss);
  698.     }
  699.     /* See if there's round-trip time experience */
  700.     if((tp = rtt_get(tcb->conn.remote.address)) != NULLRTT){
  701.         tcb->srtt = tp->srtt;
  702.         tcb->mdev = tp->mdev;
  703.     }
  704. }
  705.  
  706. /* Generate an initial sequence number and put a SYN on the send queue */
  707. void
  708. send_syn(tcb)
  709. register struct tcb *tcb;
  710. {
  711.     tcb->iss = geniss();
  712.     tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  713.     tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  714.     tcb->sndcnt++;
  715.     tcb->flags.force = 1;
  716. }
  717.  
  718. /* Add an entry to the resequencing queue in the proper place */
  719. static void
  720. add_reseq(tcb,tos,seg,bp,length)
  721. struct tcb *tcb;
  722. char tos;
  723. struct tcp *seg;
  724. struct mbuf *bp;
  725. int16 length;
  726. {
  727.     register struct reseq *rp,*rp1;
  728.  
  729.     /* Allocate reassembly descriptor */
  730.     if((rp = (struct reseq *)malloc(sizeof (struct reseq))) == NULLRESEQ){
  731.         /* No space, toss on floor */
  732.         free_p(bp);
  733.         return;
  734.     }
  735.     ASSIGN(rp->seg,*seg);
  736.     rp->tos = tos;
  737.     rp->bp = bp;
  738.     rp->length = length;
  739.  
  740.     /* Place on reassembly list sorting by starting seq number */
  741.     rp1 = tcb->reseq;
  742.     if(rp1 == NULLRESEQ || seq_lt(seg->seq,rp1->seg.seq)){
  743.         /* Either the list is empty, or we're less than all other
  744.          * entries; insert at beginning.
  745.          */
  746.         rp->next = rp1;
  747.         tcb->reseq = rp;
  748.     } else {
  749.         /* Find the last entry less than us */
  750.         for(;;){
  751.             if(rp1->next == NULLRESEQ || seq_lt(seg->seq,rp1->next->seg.seq)){
  752.                 /* We belong just after this one */
  753.                 rp->next = rp1->next;
  754.                 rp1->next = rp;
  755.                 break;
  756.             }
  757.             rp1 = rp1->next;
  758.         }
  759.     }
  760. }
  761.  
  762. /* Fetch the first entry off the resequencing queue */
  763. static void
  764. get_reseq(tcb,tos,seg,bp,length)
  765. register struct tcb *tcb;
  766. char *tos;
  767. struct tcp *seg;
  768. struct mbuf **bp;
  769. int16 *length;
  770. {
  771.     register struct reseq *rp;
  772.  
  773.     if((rp = tcb->reseq) == NULLRESEQ)
  774.         return;
  775.  
  776.     tcb->reseq = rp->next;
  777.  
  778.     *tos = rp->tos;
  779.     ASSIGN(*seg,rp->seg);
  780.     *bp = rp->bp;
  781.     *length = rp->length;
  782.     free((char *)rp);
  783. }
  784.  
  785. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  786.  * unacceptable.
  787.  */
  788. static int
  789. trim(tcb,seg,bpp,length)
  790. register struct tcb *tcb;
  791. register struct tcp *seg;
  792. struct mbuf **bpp;
  793. int16 *length;
  794. {
  795.     long dupcnt,excess;
  796.     int16 len;        /* Segment length including flags */
  797.     char accept = 0;
  798.  
  799.     len = *length;
  800.     if(seg->flags.syn)
  801.         len++;
  802.     if(seg->flags.fin)
  803.         len++;
  804.  
  805.     /* Acceptability tests */
  806.     if(tcb->rcv.wnd == 0){
  807.         /* Only in-order, zero-length segments are acceptable when
  808.          * our window is closed.
  809.          */
  810.         if(seg->seq == tcb->rcv.nxt && len == 0){
  811.             return 0;    /* Acceptable, no trimming needed */
  812.         }
  813.     } else {
  814.         /* Some part of the segment must be in the window */
  815.         if(in_window(tcb,seg->seq)){
  816.             accept++;    /* Beginning is */
  817.         } else if(len != 0){
  818.             if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  819.              seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  820.                 accept++;
  821.             }
  822.         }
  823.     }
  824.     if(!accept){
  825.         tcb->rerecv += len;    /* Assume all of it was a duplicate */
  826.         free_p(*bpp);
  827.         return -1;
  828.     }
  829.     if((dupcnt = tcb->rcv.nxt - seg->seq) > 0){
  830.         tcb->rerecv += dupcnt;
  831.         /* Trim off SYN if present */
  832.         if(seg->flags.syn){
  833.             /* SYN is before first data byte */
  834.             seg->flags.syn = 0;
  835.             seg->seq++;
  836.             dupcnt--;
  837.         }
  838.         if(dupcnt > 0){
  839.             pullup(bpp,NULLCHAR,(int16)dupcnt);
  840.             seg->seq += dupcnt;
  841.             *length -= dupcnt;
  842.         }
  843.     }
  844.     if((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0){
  845.         tcb->rerecv += excess;
  846.         /* Trim right edge */
  847.         *length -= excess;
  848.         trim_mbuf(bpp,*length);
  849.         seg->flags.fin = 0;    /* FIN follows last data byte */
  850.     }
  851.     return 0;
  852. }
  853.